/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bancodedados3d;

import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.mouse.MouseWheelZoom;
import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.geometry.*;
import java.awt.BorderLayout;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.vecmath.Vector3f;
import java.awt.Font;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Group;
import javax.vecmath.Color3f;

/**
 *
 * @author fosa
 */
public class jTable3D extends JPanel {

    private SimpleUniverse simpleU;
    TransformGroup root_group;
    BranchGroup Grupo;
    Canvas3D canvas3D;
    Box box;
    Primitive prim;
    String[][] Campos;
    String[] NomeColuna;
    Texto3D[][] Campos3D;
    Texto3D[] NomeColuna3D;
    Transform3D tabela;
    int grupos;

    public jTable3D(Object[][] rowData, Object[] columnNames) {
        canvas3D = new Canvas3D(this.getGraphicsConfiguration());
        simpleU = new SimpleUniverse(canvas3D);
//        uni = new UniversoSimples();
        initComponents();

        NomeColuna = new String[columnNames.length];
        NomeColuna3D = new Texto3D[columnNames.length];
        Campos = new String[rowData.length][1];
        Campos3D = new Texto3D[rowData.length][1];

        try {
            for (int i = 0; i < rowData.length; i++) {
                Campos[i] = new String[rowData[i].length];
                Campos3D[i] = new Texto3D[rowData[i].length];
                for (int j = 0; j < rowData[i].length; j++) {
                    Campos[i][j] = rowData[i][j].toString();
                }
            }
            for (int i = 0; i < columnNames.length; i++) {
                NomeColuna[i] = columnNames[i].toString();
            }
            vetor(-0.4f, 0.5f, NomeColuna);
            matriz(-0.4f, 0.4f, Campos);
            vetor(-0.4f, 0.5f, NomeColuna);
            matriz(-0.4f, 0.4f, Campos);
        } catch (NullPointerException nu) {
            System.out.println("nulo");
        }

        startComponents();
    }

    public jTable3D() {

//        canvas3D = new Canvas3D();
//        simpleU = new SimpleUniverse(canvas3D);
        simpleU = new SimpleUniverse();
//        uni = new UniversoSimples();
        initComponents();
//        Appearance aparencia = new Appearance();
//
//        aparencia.setColoringAttributes(new ColoringAttributes(0.5f, 0.2f, 0.8f, 3));
//        Box shap = new Box(2f, 5f, 0.001f, aparencia);
//
//        Transform3D trans = new Transform3D();
//        trans.set(new Vector3f(0f, -5f, 0f));
//        TransformGroup gruptrans = new TransformGroup(trans);
//        gruptrans.addChild(shap);
//
////        root_group.addChild(shap);
//        root_group.addChild(gruptrans);
//        root_group.addChild(shap);
        startComponents();

    }

    private void initComponents() {

        root_group = new TransformGroup();
        Grupo = new BranchGroup();
        box = new Box();


        root_group.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); // allow the mouse behavior to rotate the scene
        root_group.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        this.Grupo.addChild(root_group);  // this is the local origin  - everyone hangs off this - moving this move every one

        tabela = new Transform3D();
        tabela.setScale(0.2);       // shrink the sphere so our view point is not inside it
        TransformGroup tabelaGrupo = new TransformGroup(tabela);
        root_group.addChild(tabelaGrupo);

//        vetor(-0.4f, 0.5f, NomeColuna);
//        matriz(-0.4f, 0.4f, Campos);


//      espaço
        BoundingSphere area = new BoundingSphere(); //Area
        area.setRadius(1000.0);                     //

//      Cor do Fundo
        Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
        Background bgNode = new Background(bgColor);
        bgNode.setApplicationBounds(area);
        this.Grupo.addChild(bgNode);

        //      iluminando o espaço
        DirectionalLight luz = new DirectionalLight();
        luz.setInfluencingBounds(area);
        luz.setDirection(new Vector3f(.7f, -.7f, -.7f));  // point the light right, down, into the screen
        this.Grupo.addChild(luz);
//      ========================================

//      adicionando Movimentação pelo mouse
        MouseWheelZoom zoom = new MouseWheelZoom(root_group);
        zoom.setSchedulingBounds(new BoundingSphere());
        this.Grupo.addChild(zoom);

        MouseRotate mouseRotate = new MouseRotate(root_group);  // add the mouse behavior
        mouseRotate.setSchedulingBounds(new BoundingSphere());
        this.Grupo.addChild(mouseRotate);

        MouseTranslate mouseTranslate = new MouseTranslate(root_group);
        mouseTranslate.setSchedulingBounds(new BoundingSphere());
        this.Grupo.addChild(mouseTranslate);

//      ====================================================


    }

    private void startComponents() {
        simpleU.getViewingPlatform().setNominalViewingTransform();       // This will move the ViewPlatform back a bit so the
        Grupo.compile();
        simpleU.addBranchGraph(Grupo);

//        uni.getViewPlataform().setNominalViewingTransform();
//        uni.addBranchGraph(Grupo);

//        canvas3D = uni.getCanvas();
        canvas3D = simpleU.getCanvas();
//        canvas3D.setBounds(0, 0, 800, 600);

        this.setLayout(new BorderLayout());
        this.setOpaque(false);
        this.add("Center", canvas3D);
    }

    private void vetor(float flx, float fly, String[] str) {
        for (int i = 0; i < str.length; i++) {

            new Texto3D(flx, fly, 0.0f, str[i]);

            root_group.addChild(new Texto3D(flx, fly, 0.0f, str[i]));


            flx += 0.3f;
        }
    }

    private void matriz(float flx, float fly, String[][] str) {
        for (int i = 0; i < str.length; i++) {
            vetor(flx, fly, str[i]);
            fly -= 0.1f;
        }
    }

    public void tabela3D(String[][] str) {
        float flx = -0.4f;
        float fly = 0.2f;

        for (int j = 0; j < str.length; j++) {
            flx = -0.4f;
            for (int i = 0; i < str[j].length; i++) {
                root_group.addChild(new Texto3D(flx, fly, 0.0f, str[j][i]));
                flx += 0.3f;
            }
            fly -= 0.2f;
        }
    }

    public void setModel(Object[][] rowData, Object[] columnNames) {
        initComponents();


        Vector3f inicio = new Vector3f(-0.6f, 0.5f, 0f);
        Vector3f fim = new Vector3f();

        NomeColuna = new String[columnNames.length];
        NomeColuna3D = new Texto3D[columnNames.length];
        Campos = new String[rowData.length][1];
        Campos3D = new Texto3D[rowData.length][1];

        int[] maior = null;

        try {
            maior = new int[rowData[0].length];

            for (int i = 0; i < rowData.length; i++) {
                Campos[i] = new String[rowData[i].length];
                Campos3D[i] = new Texto3D[rowData[i].length];
                for (int j = 0; j < rowData[i].length; j++) {
                    Campos3D[i][j] = new Texto3D(Campos[i][j] = rowData[i][j].toString());

                    if (Campos[i][j].length() > maior[j]) {
                        maior[j] = Campos[i][j].length();
                    }
                }
            }

            float x = -0.6f, y = 0.5f, z = 0.05f;

            for (int i = 0; i < columnNames.length; i++) {
                NomeColuna3D[i] = new Texto3D(NomeColuna[i] = columnNames[i].toString());
                NomeColuna3D[i].setPos(x, y, z);
                NomeColuna3D[i].mudarTamanho(24);
                NomeColuna3D[i].mudarArte(Font.BOLD);

                if (NomeColuna[i].length() > maior[i]) {
                    maior[i] = NomeColuna[i].length();
                }

                x += ((0.2f * maior[i]) / 5) + 0.05;

                root_group.addChild(NomeColuna3D[i]);
            }

            y = 0.4f;
            z = 0.0f;

            for (int i = 0; i < rowData.length; i++) {
                x = -0.6f;

                for (int j = 0; j < rowData[i].length; j++) {
                    Campos3D[i][j].setPos(x, y, z);

                    x += ((0.2f * maior[j]) / 5) + 0.05f;

                    root_group.addChild(Campos3D[i][j]);
                }
                y -= 0.05f;
            }


            fim = new Vector3f(x, y, z);

            createbox(inicio, fim);
        } catch (NullPointerException nu) {
            nu.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException arr) {
            arr.printStackTrace();
        }


//        Appearance apar = new Appearance();
//        apar.setColoringAttributes(new ColoringAttributes(0.5f, 0.5f, 0.5f, 1));
//        box = new Box(inicio.getX(), fim.getY(), 0, 5, apar);

        startComponents();
    }

    public void setModel(Object[][] rowData, Object[] columnNames, float z) {
        initComponents();


        Vector3f inicio = new Vector3f(-0.6f, 0.5f, 0f);
        Vector3f fim = new Vector3f();

        NomeColuna = new String[columnNames.length];
        NomeColuna3D = new Texto3D[columnNames.length];
        Campos = new String[rowData.length][1];
        Campos3D = new Texto3D[rowData.length][1];

        int[] maior = null;

        try {
            maior = new int[rowData[0].length];

            for (int i = 0; i < rowData.length; i++) {
                Campos[i] = new String[rowData[i].length];
                Campos3D[i] = new Texto3D[rowData[i].length];
                for (int j = 0; j < rowData[i].length; j++) {
                    Campos3D[i][j] = new Texto3D(Campos[i][j] = rowData[i][j].toString());

                    if (Campos[i][j].length() > maior[j]) {
                        maior[j] = Campos[i][j].length();
                    }
                }
            }

            float x = inicio.getX(), y = inicio.getY();
            z += 0.05f;

            for (int i = 0; i < columnNames.length; i++) {
                NomeColuna3D[i] = new Texto3D(NomeColuna[i] = columnNames[i].toString());
                NomeColuna3D[i].setPos(x, y, z);
                NomeColuna3D[i].mudarTamanho(24);
                NomeColuna3D[i].mudarArte(Font.BOLD);

                if (NomeColuna[i].length() > maior[i]) {
                    maior[i] = NomeColuna[i].length();
                }

                x += ((0.2f * maior[i]) / 5) + 0.05;

                root_group.addChild(NomeColuna3D[i]);
            }

            y = 0.4f;
            z -= 0.05f;

            for (int i = 0; i < rowData.length; i++) {
                x = -0.6f;

                for (int j = 0; j < rowData[i].length; j++) {
                    Campos3D[i][j].setPos(x, y, z);

                    x += ((0.2f * maior[j]) / 5) + 0.05f;

                    root_group.addChild(Campos3D[i][j]);
                }
                y -= 0.05f;
            }


            fim = new Vector3f(x, y, z);
        } catch (NullPointerException nu) {
            nu.printStackTrace();
        }

        createbox(inicio, fim);

//        Appearance apar = new Appearance();
//        apar.setColoringAttributes(new ColoringAttributes(0.9f, 0.9f, 0.2f, 1));
//        box = new Box(0, 1, -0.5f, 5, apar);

        startComponents();
    }

    static public void main(String[] args) {
        JFrame frame = new JFrame();
        jTable3D tab1 = new jTable3D();
        final JTextField jTextField1 = new javax.swing.JTextField();

        jTextField1.setText("");

        jTextField1.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });


        frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        frame.setLayout(new BorderLayout());
        frame.add(BorderLayout.CENTER, tab1);
        frame.add(BorderLayout.PAGE_END, jTextField1);

        tab1.setModel(new Object[][]{{"linha1", "linha1"}, {"linha2", "linha2"}, {"linha3", "linha3"}}, new Object[]{"coluna1", "coluna2"});
        tab1.setModel(new Object[][]{{"linha1", "linha1"}, {"linha2", "linha2"}, {"linha3", "linha3"}}, new Object[]{"coluna1", "coluna2"}, 1);

        frame.pack();


        frame.show();
    }

    private static void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
    }

    private Group createbox(Vector3f _inicio, Vector3f _fim) {

//        System.out.println(_inicio + " " + _fim);

        Appearance aparencia = new Appearance();
        aparencia.setColoringAttributes(new ColoringAttributes(0.5f, 0.2f, 0.8f, 3));

        float tamX = (_inicio.getX() - _fim.getX()) * 0.5f;
        float tamY = (_inicio.getY() - _fim.getY()) * 0.5f;

        if (tamX < 0) {
            tamX *= -1;
        }
        if (tamY < 0) {
            tamY *= -1;
        }

        System.out.println(_inicio + " " + _fim + " - " + tamX + " " + tamY);

        Box shap = new Box(tamX, tamY, 0.01f, aparencia);

        Transform3D trans = new Transform3D();
        trans.set(new Vector3f((tamX) - (_inicio.getX()), -((tamY ) - _inicio.getY()), _fim.getZ() - 0.1f));
//        trans.set(_inicio);
//        trans.set(new Vector3f(5.0f,-5.0f,0.0f));
        TransformGroup gruptrans = new TransformGroup(trans);
        gruptrans.addChild(shap);


//        root_group.addChild(shap);
        root_group.addChild(gruptrans);
//        root_group.addChild(shap);









        return gruptrans;
    }
}
